package com.wg.net.server.http;

import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.wg.core.controller.ControllerMgr;
import com.wg.core.controller.IController;
import com.wg.core.counter.CounterMgr;
import com.wg.net.annotation.HttpRequestMapping;
import io.netty.handler.codec.http.HttpResponseStatus;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * HTTP请求处理管理器（线程安全、支持动态注册、增强可观测性）
 *
 * @author 少爷123
 */
public class HandleHttpClientRequestMgr {
    private static final Log log = LogFactory.get();
    /**
     * 线程安全的处理器映射
     */
    private final ConcurrentHashMap<String, HandleWrapper> handlerMap = new ConcurrentHashMap<>(128);

    private HandleHttpClientRequestMgr() {
    }

    /**
     * 获取单例实例（支持依赖注入）
     */
    public static HandleHttpClientRequestMgr getInstance() {
        return Singleton.INSTANCE.getManager();
    }

    /**
     * 初始化请求处理器（扫描注解并注册）
     *
     * @param basePackage 扫描的基础包路径（如"com.wg.controller"）
     */
    public void init(String basePackage) {
        Set<Class<?>> controllerClasses = ClassUtil.scanPackageByAnnotation(basePackage, HttpRequestMapping.class);
        if (controllerClasses.isEmpty()) {
            return;
        }

        for (Class<?> controllerClass : controllerClasses) {
            HttpRequestMapping mapping = controllerClass.getAnnotation(HttpRequestMapping.class);
            if (mapping == null) {
                continue;
            }

            String requestUri = mapping.value();
            if (handlerMap.containsKey(requestUri)) {
                log.warn("请求URI重复注册 | URI: {}, 类: {}", requestUri, controllerClass.getName());
                continue;
            }

            try {
                // 实例化控制器（通过ControllerMgr获取，支持依赖注入）
                IController controller = ControllerMgr.getInstance().getController(mapping.controller());
                if (controller == null) {
                    log.error("控制器实例化失败 | 控制器类: {}", controllerClass.getName());
                    continue;
                }

                // 实例化请求处理器（通过反射创建，支持后续缓存优化）
                IHandleHttpRequest handler = (IHandleHttpRequest) ReflectUtil.newInstance(controllerClass);
                if (handler == null) {
                    log.error("请求处理器实例化失败 | 控制器类: {}", controllerClass.getName());
                    continue;
                }

                // 构建处理器包装器
                HandleWrapper wrapper = new HandleWrapper(
                        handler,
                        controller,
                        mapping.method(),
                        mapping.maxExeTimeMs() * 1_000_000L,
                        mapping.publicIpAccess());

                handlerMap.put(requestUri, wrapper);
                log.info("成功注册请求处理器 | URI: {}, 控制器: {}, 方法: {}",
                        requestUri, controllerClass.getSimpleName(), mapping.method());
            } catch (Exception e) {
                log.error("控制器/处理器实例化异常 | 类: {}", controllerClass.getName(), e);
            }
        }
    }

    /**
     * 根据请求URI获取处理器包装器
     */
    public HandleWrapper getHandleWrapper(String requestUri) {
        return handlerMap.get(requestUri);
    }

    /**
     * 动态注册请求处理器（运行时扩展）
     *
     * @param requestUri 请求URI
     * @param wrapper    处理器包装器
     */
    public void registerHandler(String requestUri, HandleWrapper wrapper) {
        if (StrUtil.isBlank(requestUri) || wrapper == null) {
            log.warn("动态注册失败 | URI为空或包装器为空");
            return;
        }
        handlerMap.put(requestUri, wrapper);
        log.info("动态注册请求处理器 | URI: {}", requestUri);
    }

    /**
     * 动态注销请求处理器（运行时扩展）
     *
     * @param requestUri 请求URI
     */
    public void unregisterHandler(String requestUri) {
        if (StrUtil.isBlank(requestUri)) {
            log.warn("动态注销失败 | URI为空");
            return;
        }
        HandleWrapper removed = handlerMap.remove(requestUri);
        if (removed != null) {
            log.info("动态注销请求处理器 | URI: {}", requestUri);
        }
    }

    /**
     * 处理器包装器（封装请求处理逻辑）
     */
    public static class HandleWrapper {
        private final IHandleHttpRequest handler;
        private final IController controller;
        private final HttpMethod method;
        private final long maxExeTimeNs;
        private final boolean publicIpAccess;

        public HandleWrapper(IHandleHttpRequest handler, IController controller,
                             HttpMethod method, long maxExeTimeNs, boolean publicIpAccess) {
            this.handler = handler;
            this.controller = controller;
            this.method = method;
            this.maxExeTimeNs = maxExeTimeNs;
            this.publicIpAccess = publicIpAccess;
        }

        public HttpMethod getMethod() {
            return method;
        }

        public boolean isPublicIpAccess() {
            return publicIpAccess;
        }

        /**
         * 执行请求处理（支持异步）
         */
        public void handleRequest(HttpServletRequest request, HttpServletResponse response) {
            if (controller != null) {
                controller.getFiber().enqueue(() -> doExecute(request, response));
            } else {
                doExecute(request, response);
            }
        }

        /**
         * 实际执行处理逻辑（含性能监控）
         */
        private void doExecute(HttpServletRequest request, HttpServletResponse response) {
            long startTimeNs = System.nanoTime();
            long interval = request.getHandleInterval().intervalRestart();

            try {
                handler.execute(request, response);
            } catch (Exception e) {
                log.error("请求处理异常 | URI: {}, 处理器: {}", request.getUri(), handler.getClass().getSimpleName(), e);
                response.writeAndFlush(HttpResponseStatus.INTERNAL_SERVER_ERROR, "处理异常: " + e.getMessage());
                return;
            } finally {
                // 触发后置拦截器
                HandlerInterceptorMgr.getInstance().triggerPostHandle(request, response, handler);

                // 计算执行耗时并记录
                long exeTimeNs = System.nanoTime() - startTimeNs;
                long totalIntervalNs = interval + exeTimeNs;

                // 记录性能指标
                CounterMgr.getInstance().getHttpAverage().addValue(totalIntervalNs / 1_000_000);

                String logMsg = StrUtil.format(
                        "{} | ID: {} | URI: {} | 总耗时: {:.2f}ms | 执行耗时: {:.2f}ms | 最大允许: {:.2f}ms",
                        handler.getClass().getSimpleName(),
                        request.getId(),
                        request.getUri(),
                        totalIntervalNs / 1_000_000.0,
                        exeTimeNs / 1_000_000.0,
                        maxExeTimeNs / 1_000_000.0);

                if (totalIntervalNs > maxExeTimeNs) {
                    log.error("请求处理超时 | {}", logMsg);
                } else {
                    log.debug("请求处理完成 | {}", logMsg);
                }
            }
        }
    }

    private enum Singleton {
        INSTANCE;

        HandleHttpClientRequestMgr manager;

        Singleton() {
            this.manager = new HandleHttpClientRequestMgr();
        }

        public HandleHttpClientRequestMgr getManager() {
            return manager;
        }
    }
}
